package com.ihr360.payroll.service.salaryreport.impl;

import com.google.common.collect.Lists;
import com.ihr360.commons.lang.CollectionUtils;
import com.ihr360.commons.vo.PageData;
import com.ihr360.entity.BasicStaffInfoEntity;
import com.ihr360.payroll.dao.MergeReportStaffSalaryRepository;
import com.ihr360.payroll.model.dto.salary.report.MergeReportStaffSalary;
import com.ihr360.payroll.model.dto.salary.task.period.embeddable.StaffSalarySnapshot;
import com.ihr360.payroll.model.response.salaryreport.StaffSalaryData;
import com.ihr360.payroll.model.response.salaryreport.StaffSalaryResponse;
import com.ihr360.payroll.request.salaryReport.MergeSalaryQueryRequest;
import com.ihr360.payroll.service.salaryreport.MergeReportStaffSalaryService;
import com.ihr360.rest.reposity.SimpleRestReposity;
import com.ihr360.rest.service.AbstractSimpleRestServiceImpl;
import com.ihr360.shared.basicstaffinfo.service.BasicStaffInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by Eric on 2018/4/11/011.
 */
@Service
public class MergeReportStaffSalaryServiceImpl extends AbstractSimpleRestServiceImpl<MergeReportStaffSalary, Long> implements MergeReportStaffSalaryService {

    @Autowired
    private MergeReportStaffSalaryRepository mergeReportStaffSalaryRepository;

    @Autowired
    private BasicStaffInfoService basicStaffInfoService;

    @Override
    public SimpleRestReposity<MergeReportStaffSalary, Long> getSimpleRestReposity() {
        return mergeReportStaffSalaryRepository;
    }

    @Override
    public PageData<StaffSalaryResponse> queryStaffSalaryPage(String companyId, MergeSalaryQueryRequest reportRequest, Long termSalaryId) {
        List<StaffSalaryResponse> responseList = Lists.newArrayList();
        Page<MergeReportStaffSalary> page = mergeReportStaffSalaryRepository.findByCompanyIdAndTermSalaryId(companyId, termSalaryId, reportRequest.getPageable());
        if (page == null || CollectionUtils.isEmpty(page.getContent())) {
            return new PageData<>(0, 0, responseList);
        }
        List<String> staffIds = page.getContent().stream().map(mergeReportStaffSalary -> mergeReportStaffSalary.getId().getStaffId()).collect(Collectors.toList());
        List<BasicStaffInfoEntity> staffInfoList = basicStaffInfoService.getStaffList(companyId, staffIds);
        Map<String, BasicStaffInfoEntity> staffMap = staffInfoList.stream().collect(Collectors.toMap(BasicStaffInfoEntity::getId, Function.identity()));
        page.getContent().forEach(staffSalary -> {
            StaffSalaryResponse response = dtoToResponse(staffSalary, staffMap);
            if (response != null) {
                responseList.add(response);
            }
        });
        return new PageData<>(page.getTotalPages(), page.getTotalElements(), responseList);
    }

    @Override
    public PageData<StaffSalaryResponse> queryStaffListSalaryPage(String companyId, List<String> staffIdList, Long termSalaryId, Pageable pageable) {
        List<StaffSalaryResponse> responseList = Lists.newArrayList();
        Page<MergeReportStaffSalary> page = mergeReportStaffSalaryRepository.findByCompanyIdAndIdStaffIdInAndTermSalaryId(companyId, staffIdList, termSalaryId, pageable);
        if (page == null || CollectionUtils.isEmpty(page.getContent())) {
            return new PageData<>(0, 0, responseList);
        }
        List<String> staffIds = page.getContent().stream().map(mergeReportStaffSalary -> mergeReportStaffSalary.getId().getStaffId()).collect(Collectors.toList());
        List<BasicStaffInfoEntity> staffInfoList = basicStaffInfoService.getStaffList(companyId, staffIds);
        Map<String, BasicStaffInfoEntity> staffMap = staffInfoList.stream().collect(Collectors.toMap(BasicStaffInfoEntity::getId, Function.identity()));
        page.getContent().forEach(staffSalary -> {
            StaffSalaryResponse response = dtoToResponse(staffSalary, staffMap);
            if (response != null) {
                responseList.add(response);
            }
        });
        return new PageData<>(page.getTotalPages(), page.getTotalElements(), responseList);
    }

    @Override
    public List<StaffSalaryResponse> queryStaffSalaryList(String companyId, Long termSalaryId) {
        List<StaffSalaryResponse> responseList = Lists.newArrayList();
        List<MergeReportStaffSalary> list = mergeReportStaffSalaryRepository.findByCompanyIdAndTermSalaryId(companyId, termSalaryId);
        if (CollectionUtils.isEmpty(list)) {
            return responseList;
        }
        List<String> staffIds = list.stream().map(mergeReportStaffSalary -> mergeReportStaffSalary.getId().getStaffId()).collect(Collectors.toList());
        List<BasicStaffInfoEntity> staffInfoList = basicStaffInfoService.getStaffList(companyId, staffIds);
        Map<String, BasicStaffInfoEntity> staffMap = staffInfoList.stream().collect(Collectors.toMap(BasicStaffInfoEntity::getId, Function.identity()));
        list.forEach(staffSalary -> {
            StaffSalaryResponse response = dtoToResponse(staffSalary, staffMap);
            if (response != null) {
                responseList.add(response);
            }
        });
        return responseList;
    }

    private StaffSalaryResponse dtoToResponse(MergeReportStaffSalary staffSalary, Map<String, BasicStaffInfoEntity> staffMap) {
        if (staffSalary == null) {
            return null;
        }
        StaffSalaryResponse response = new StaffSalaryResponse();
        response.setStaffId(staffSalary.getId().getStaffId());
        if (staffSalary.getSummarizedData() != null) {
            StaffSalaryData summaryData = new StaffSalaryData();
            BeanUtils.copyProperties(staffSalary.getSummarizedData(), summaryData);
            response.setSummaryData(summaryData);
        }
        if (staffSalary.getPhasedData() != null && CollectionUtils.isNotEmpty(staffSalary.getPhasedData().getPhasedData())
                && staffSalary.getPhasedData().getPhasedData().size() > 1) {
            List<StaffSalarySnapshot> list = staffSalary.getPhasedData().getPhasedData();
            List<StaffSalaryData> phasedData = Lists.newArrayList();
            list.forEach(staffSalarySnapshot -> {
                StaffSalaryData data = new StaffSalaryData();
                BeanUtils.copyProperties(staffSalarySnapshot, data);
                phasedData.add(data);
            });
            response.setPhasedData(phasedData);
        }
        BasicStaffInfoEntity staffInfoEntity = staffMap.get(response.getStaffId());
        if (staffInfoEntity != null) {
            response.setDepartmentName(staffInfoEntity.getDepartmentName());
            response.setMobileNo(staffInfoEntity.getMobileNo());
            response.setStaffName(staffInfoEntity.getStaffName());
        }
        return response;
    }
}
